﻿using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;

namespace Nirvana
{
    [CustomEditor(typeof(QualityMaterialArrayControl), true)]
    public class QualityMaterialArrayControlEditor : Editor
    {
        private class QualityMaterilProperty
        {
            public SerializedProperty property;
            public QualityMaterialArrayControlEditor mateditor;

            public void DrawMaterial(Rect rect, int index, bool isActive, bool isFocused)
            {
                this.mateditor.DrawMaterial(this.property, rect, index, isActive, isFocused);
            }
        }

        private QualityConfig qualityConfig;
        private SerializedProperty controls;
        private ReorderableList controlList;
        private Dictionary<string, ReorderableList> matsMap = new Dictionary<string, ReorderableList>();
        private int currentLevel=1;
        public override void OnInspectorGUI()
        {

            if (this.qualityConfig == null)
            {
                var qualityConfigs = QualityConfig.FindConfigs();
                if (qualityConfigs.Length == 0)
                {
                    EditorGUILayout.HelpBox("There has no quality config in the project.", MessageType.Error);
                    this.qualityConfig = null;
                }
                else
                {
                    if (qualityConfigs.Length > 1)
                    {
                        EditorGUILayout.HelpBox("There are more than one quality config.", MessageType.Warning);
                    }
                    this.qualityConfig = qualityConfigs[0];
                }
            }

            if (this.qualityConfig != null)
            {
                var levelCount = this.qualityConfig.GetLevelCount();
                var qualityMenu = new string[levelCount];
                for (int i = 0; i < levelCount; ++i)
                {
                    var level = this.qualityConfig.GetLevel(i);
                    qualityMenu[i] = level.Name;
                }

                EditorGUILayout.Space();
                EditorGUILayout.Space();
                EditorGUI.BeginChangeCheck();
                currentLevel = EditorGUILayout.Popup("Test Current Quality:", currentLevel, qualityMenu);
                if (EditorGUI.EndChangeCheck())
                {
                    var ctrl = target as QualityMaterialArrayControl;
                    //ctl.SetQualityLevel(currentLevel);
                    QualityConfig.QualityLevel = currentLevel; //美术测试用
                }

                EditorGUILayout.Space();
                EditorGUILayout.Space();
            }

            // Draw the editor.
            this.serializedObject.Update();
            this.controlList.DoLayoutList();
            this.serializedObject.ApplyModifiedProperties();
        }

        private void OnEnable()
        {
            if (this.target == null)
            {
                return;
            }

            this.controls = this.serializedObject.FindProperty("controls");
            this.controlList = new ReorderableList(serializedObject, this.controls);
            this.controlList.drawHeaderCallback = OnDrawHead;
            this.controlList.elementHeightCallback = DrawElementHeight;
            this.controlList.drawElementCallback = this.DrawControl;

        }
        private void OnDrawHead(Rect rect)
        {
            GUI.Label(rect, "Material Array:");
        }
        private float DrawElementHeight(int height)
        {
            SerializedProperty arrayElementAtIndex = this.controls.GetArrayElementAtIndex(height);
            if (!arrayElementAtIndex.isExpanded)
            {
                return 1.2f * EditorGUIUtility.singleLineHeight;
            }
            SerializedProperty serializedProperty = arrayElementAtIndex.FindPropertyRelative("Target");
            if (serializedProperty.arraySize > 0)
            {
                return (5.75f + (float)serializedProperty.arraySize) * EditorGUIUtility.singleLineHeight;
            }
            return 7f * EditorGUIUtility.singleLineHeight;
        }
        private void DrawControl(Rect rect, int index, bool isActive, bool isFocused)
        {
            var element = this.controls.GetArrayElementAtIndex(index);
            rect.x += 10f;
            rect.width -= 10f;
            //展开栏范围大小
            GUI.color = Color.yellow;
            var newRect = new Rect(rect.x, rect.y, rect.width, EditorGUIUtility.singleLineHeight);
            element.isExpanded = EditorGUI.Foldout(newRect, element.isExpanded, new GUIContent(string.Format("Quality{0}:", index)));
            GUI.color = Color.white;
            if (!element.isExpanded)
            {
                return;
            }

            var target = element.FindPropertyRelative("Target");
            var enabledLevels = element.FindPropertyRelative("EnabledLevels");
            newRect.y += 1.25f * EditorGUIUtility.singleLineHeight;

            if (this.qualityConfig == null)
            {
                var origin = GUI.color;
                GUI.color = Color.red;
                GUI.Label(newRect, "Missing quality config.");
                GUI.color = origin;
            }
            else
            {
                var rectLine = new Rect(newRect.x, newRect.y, newRect.width / 3f, EditorGUIUtility.singleLineHeight);
                GUI.Label(rectLine, "QualityLevel Enable:");

                int levelCount = this.qualityConfig.GetLevelCount();
                enabledLevels.arraySize = levelCount;

                float itemWidth = (newRect.width - rectLine.width) / levelCount;
                float startX = newRect.x + rectLine.width + 6f;

                // Draw the toggle
                for (int i = 0; i < levelCount; ++i)
                {
                    var level = this.qualityConfig.GetLevel(i);
                    GUIContent levelname = new GUIContent(level.Name);
                    var rectItem = new Rect(startX + itemWidth * i, newRect.y, itemWidth, EditorGUIUtility.singleLineHeight);

                    var levelEnabled = enabledLevels.GetArrayElementAtIndex(i);
                    levelEnabled.boolValue = GUI.Toggle(rectItem, levelEnabled.boolValue, levelname);
                }
            }

            // Draw Materials array
            newRect.y += 1.5f * EditorGUIUtility.singleLineHeight;
            ReorderableList reorderableList = this.DrawMaterialArrayUI(target);
            reorderableList.DoList(newRect);
        }

        private ReorderableList DrawMaterialArrayUI(SerializedProperty target)
        {
            QualityMaterilProperty materilProperty = new QualityMaterilProperty();
            materilProperty.property = target;
            materilProperty.mateditor = this;
            ReorderableList reorderableList;
            if (this.matsMap.TryGetValue(materilProperty.property.propertyPath, out reorderableList))
            {
                return reorderableList;
            }
            reorderableList = new ReorderableList(materilProperty.property.serializedObject, materilProperty.property);
            reorderableList.drawHeaderCallback = (r) => { GUI.Label(r, "Materials:"); };
            reorderableList.elementHeight = EditorGUIUtility.singleLineHeight;
            reorderableList.drawElementCallback = materilProperty.DrawMaterial;
            this.matsMap.Add(materilProperty.property.propertyPath, reorderableList);
            return reorderableList;
        }
        private void DrawMaterial(SerializedProperty property, Rect rect, int index, bool isActive, bool isFocused)
        {
            var element = property.GetArrayElementAtIndex(index);
            EditorGUI.PropertyField(rect, element, GUIContent.none);
        }

    }
}

